home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-src / type_expr.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  50KB  |  1,197 lines

  1. /*  $VER: vbcc (type_expr.c) V0.4   */
  2.  
  3. #include "vbc.h"
  4.  
  5. static char FILE_[]=__FILE__;
  6.  
  7. int alg_opt(np),type_expression2(np);
  8. int test_assignment(struct Typ *,np);
  9. void make_cexpr(np);
  10.  
  11. int dontopt;
  12.  
  13. void insert_const(np p)
  14. /*  Spezialfall fuer np */
  15. {
  16.     if(!p||!p->ntyp) ierror(0);
  17.     insert_const2(&p->val,p->ntyp->flags);
  18. }
  19. int const_typ(struct Typ *p)
  20. /*  Testet, ob Typ konstant ist oder konstante Elemente enthaelt    */
  21. {
  22.     int i;struct struct_declaration *sd;
  23.     if(p->flags&CONST) return(1);
  24.     if(p->flags==STRUCT||p->flags==UNION)
  25.         for(i=0;i<p->exact->count;i++)
  26.             if(const_typ((*p->exact->sl)[i].styp)) return(1);
  27.     return(0);
  28. }
  29. struct Typ *arith_typ(struct Typ *a,struct Typ *b)
  30. /*  Erzeugt Typ fuer arithmetische Umwandlung von zwei Operanden    */
  31. {
  32.     int ta,tb;struct Typ *new;
  33.     new=mymalloc(TYPS);
  34.     new->next=0;
  35.     ta=a->flags&NU;tb=b->flags&NU;
  36.     if(ta==DOUBLE||tb==DOUBLE){new->flags=DOUBLE;return(new);}
  37.     if(ta==FLOAT||tb==FLOAT){new->flags=FLOAT;return(new);}
  38.     ta=int_erw(ta);tb=int_erw(tb);
  39.     if(ta==(UNSIGNED|LONG)||tb==(UNSIGNED|LONG)){new->flags=UNSIGNED|LONG;return(new);}
  40.     if((ta==LONG&&tb==(UNSIGNED|INT))||(ta==(UNSIGNED|INT)&&tb==LONG)){
  41.         if(UINT_MAX<=LONG_MAX) new->flags=LONG; else new->flags=UNSIGNED|LONG;
  42.         return(new);
  43.     }
  44.     if(ta==LONG||tb==LONG){new->flags=LONG;return(new);}
  45.     if(ta==(UNSIGNED|INT)||tb==(UNSIGNED|INT)){new->flags=UNSIGNED|INT;return(new);}
  46.     new->flags=INT;
  47.     return(new);
  48. }
  49. int int_erw(int t)
  50. /*  Fuehrt Integer_Erweiterung eines Typen durch                */
  51. {
  52.     if((t&NQ)>SHORT) return(t);
  53.     if((t&NU)==CHAR&&SCHAR_MAX<=INT_MAX) return(INT);
  54.     if((t&NU)==SHORT&&SHRT_MAX<=INT_MAX) return(INT);
  55.     if((t&NU)==(UNSIGNED|CHAR)&&UCHAR_MAX<=INT_MAX) return(INT);
  56.     if((t&NU)==(UNSIGNED|SHORT)&&USHRT_MAX<=INT_MAX) return(INT);
  57.     return(UNSIGNED|INT);
  58. }
  59. int type_expression(np p)
  60. /*  Art Frontend fuer type_expression2(). Setzt dontopt auf 0   */
  61. {
  62.     dontopt=0;
  63.     return(type_expression2(p));
  64. }
  65. int type_expression2(np p)
  66. /*  Erzeugt Typ-Strukturen fuer jeden Knoten des Baumes und     */
  67. /*  liefert eins zurueck, wenn der Baum ok ist, sonst 0         */
  68. /*  Die Berechnung von Konstanten und andere Vereinfachungen    */
  69. /*  sollten vielleicht in eigene Funktion kommen                */
  70. {
  71.     int ok,f=p->flags,mopt=dontopt;
  72.     if(!p){ierror(0);return(1);}
  73. /*    if(p->ntyp) printf("Warnung: ntyp!=0\n");*/
  74.     p->lvalue=0;
  75.     p->sidefx=0;
  76.     ok=1;
  77.     if(f==CALL&&p->left->flags==IDENTIFIER&&!find_var(p->left->identifier,0)){
  78.     /*  implizite Deklaration bei Aufruf einer Funktion     */
  79.         struct struct_declaration *sd;struct Typ *t;
  80.         error(161,p->left->identifier);
  81.         sd=mymalloc(sizeof(*sd));
  82.         sd->count=0;
  83.         t=mymalloc(TYPS);
  84.         t->flags=FUNKT;
  85.         t->exact=add_sd(sd);
  86.         t->next=mymalloc(TYPS);
  87.         t->next->next=0;
  88.         t->next->flags=INT;
  89.         add_var(p->left->identifier,t,EXTERN,0);
  90.     }
  91.     dontopt=0;
  92.     if(f==ADDRESS&&p->left->flags==IDENTIFIER) {p->left->flags|=256;/*puts("&const");*/}
  93.     if(p->left&&p->flags!=ASSIGNADD){ struct struct_declaration *sd;
  94.     /*  bei ASSIGNADD wird der linke Zweig durch den Link bewertet  */
  95.         ok&=type_expression2(p->left); p->sidefx|=p->left->sidefx;
  96.         if(!ok) return(0);
  97.     }
  98.     if(p->right&&p->right->flags!=MEMBER){ struct struct_declaration *sd;
  99.         if(p->flags==ASSIGNADD) dontopt=1; else dontopt=0;
  100.         ok&=type_expression2(p->right); p->sidefx|=p->right->sidefx;
  101.         if(!ok) return(0);
  102.     }
  103.  
  104. /*    printf("bearbeite %s\n",ename[p->flags]);*/
  105. /*  Erzeugung von Zeigern aus Arrays                            */
  106. /*  Hier muss noch einiges genauer werden (wie gehoert das?)    */
  107.     if(p->left&&((p->left->ntyp->flags&NQ)==ARRAY||(p->left->ntyp->flags&NQ)==FUNKT)){
  108.         if(f!=ADDRESS&&f!=ADDRESSA&&f!=ADDRESSS&&f!=FIRSTELEMENT&&f!=DSTRUCT&&(f<PREINC||f>POSTDEC)&&(f<ASSIGN||f>ASSIGNRSHIFT)){
  109.             np new=mymalloc(NODES);
  110.             if((p->left->ntyp->flags&NQ)==ARRAY) new->flags=ADDRESSA;
  111.              else new->flags=ADDRESS;
  112.             new->ntyp=0;
  113.             new->left=p->left;
  114.             new->right=0;new->lvalue=0;new->sidefx=0; /* sind sidefx immer 0? */
  115.             p->left=new;
  116.             ok&=type_expression2(p->left);
  117.         }
  118.     }
  119.     if(p->right&&f!=FIRSTELEMENT&&f!=DSTRUCT&&f!=ADDRESSS&&((p->right->ntyp->flags&NQ)==ARRAY||(p->right->ntyp->flags&NQ)==FUNKT)){
  120.             np new=mymalloc(NODES);
  121.             if((p->right->ntyp->flags&NQ)==ARRAY) new->flags=ADDRESSA;
  122.              else new->flags=ADDRESS;
  123.             new->ntyp=0;
  124.             new->left=p->right;
  125.             new->right=0;new->lvalue=0;new->sidefx=0; /* sind sidefx immer 0? */
  126.             p->right=new;
  127.             ok&=type_expression2(p->right);
  128.     }
  129.  
  130.     if(f==IDENTIFIER||f==(IDENTIFIER|256)){
  131.         int ff;struct Var *v;
  132.         v=find_var(p->identifier,0);
  133.         if(v==0){error(82,p->identifier);return(0);}
  134.         ff=v->vtyp->flags&NQ;
  135.         if((ff>=CHAR&&ff<=DOUBLE)||ff==POINTER||ff==STRUCT||ff==UNION/*||ff==ARRAY*/) p->lvalue=1;
  136.         p->ntyp=clone_typ(v->vtyp);
  137.         /*  arithmetischen const Typ als Konstante behandeln, das muss noch
  138.             deutlich anders werden, bevor man es wirklich so machen kann
  139.         if((p->ntyp->flags&CONST)&&arith(p->ntyp->flags&NQ)&&v->clist&&!(f&256)){
  140.             p->flags=CEXPR;
  141.             p->val=v->clist->val;
  142.             v->flags|=USEDASSOURCE;
  143.         }*/
  144.         p->flags&=~256;
  145.         if((p->ntyp->flags&NQ)==ENUM){
  146.         /*  enumerations auch als Konstante (int) behandeln */
  147.             p->flags=CEXPR;
  148.             if(!v->clist) ierror(0);
  149.             p->val=v->clist->val;
  150.             p->ntyp->flags=CONST|INT;
  151.         }
  152.         p->o.v=v;
  153.         return(1);
  154.     }
  155.  
  156.     if(f==CEXPR||f==PCEXPR||f==STRING) return(1);
  157.  
  158.     if(f==KOMMA){
  159.         p->ntyp=clone_typ(p->right->ntyp);
  160.         if(f==CEXPR) p->val=p->right->val;
  161.         return(ok);
  162.     }
  163.     if(f==ASSIGN||f==ASSIGNADD){
  164.         if(!p){ierror(0);return(0);}
  165.         if(!p->left){ierror(0);return(0);}
  166.         if(p->left->lvalue==0) {error(86);/*prd(p->left->ntyp);*/return(0);}
  167.         if(const_typ(p->left->ntyp)) {error(87);return(0);}
  168.         if(type_uncomplete(p->left->ntyp)) {error(88);return(0);}
  169.         if(type_uncomplete(p->right->ntyp)) {error(88);return(0);}
  170.         p->ntyp=clone_typ(p->left->ntyp);
  171.         p->sidefx=1;
  172.         return(test_assignment(p->left->ntyp,p->right));
  173.     }
  174.     if(f==LOR||f==LAND){
  175.         int a1=-1,a2=-1,m;
  176.         if(f==LAND) m=1; else m=0;
  177.         p->ntyp=mymalloc(TYPS);
  178.         p->ntyp->flags=INT;p->ntyp->next=0;
  179.         if(!arith(p->left->ntyp->flags&NQ)&&(p->left->ntyp->flags&NQ)!=POINTER)
  180.             {error(89);ok=0;}
  181.         if(!arith(p->right->ntyp->flags&NQ)&&(p->right->ntyp->flags&NQ)!=POINTER)
  182.             {error(89);ok=0;}
  183.         if(p->left->flags==CEXPR){
  184.             eval_constn(p->left);
  185.             if(!zdeqto(vdouble,d2zd(0.0))||!zuleqto(vulong,ul2zul(0UL))||!zleqto(vlong,l2zl(0L))) a1=1; else a1=0;
  186.         }
  187.         if(p->right->flags==CEXPR){
  188.             eval_constn(p->right);
  189.             if(!zdeqto(vdouble,d2zd(0.0))||!zuleqto(vulong,ul2zul(0UL))||!zleqto(vlong,l2zl(0L))) a2=1; else a2=0;
  190.         }
  191.         if(a1==1-m||a2==1-m||(a1==m&&a2==m)){
  192.             p->flags=CEXPR;p->sidefx=0;
  193.             if(!p->left->sidefx) {free_expression(p->left);p->left=0;} else p->sidefx=1;
  194.             if(!p->right->sidefx||a1==1-m) {free_expression(p->right);p->right=0;} else p->sidefx=0;
  195.             if(a1==1-m||a2==1-m) {p->val.vint=zl2zi(l2zl((long)(1-m)));}
  196.              else {p->val.vint=zl2zi(l2zl((long)m));}
  197.         }
  198.         return(ok);
  199.     }
  200.     if(f==OR||f==AND||f==XOR){
  201.         if(((p->left->ntyp->flags&NQ)<CHAR)||((p->left->ntyp->flags&NQ)>LONG)){error(90);return(0);}
  202.         if(((p->right->ntyp->flags&NQ)<CHAR)||((p->right->ntyp->flags&NQ)>LONG)){error(90);return(0);}
  203.         p->ntyp=arith_typ(p->left->ntyp,p->right->ntyp);
  204.         if(!mopt){
  205.             if(!alg_opt(p)) ierror(0);
  206.         }
  207.         return(ok);
  208.     }
  209.     if(f==LESS||f==LESSEQ||f==GREATER||f==GREATEREQ||f==EQUAL||f==INEQUAL){
  210.     /*  hier noch einige Abfragen fuer sichere Entscheidungen einbauen  */
  211.     /*  z.B. unigned/signed-Vergleiche etc.                             */
  212.     /*  die val.vint=0/1-Zuweisungen muessen noch an zint angepasst     */
  213.     /*  werden                                                          */
  214.         zlong s1,s2;zulong u1,u2;zdouble d1,d2;int c=0;
  215.         struct Typ *t;
  216.         if(!arith(p->left->ntyp->flags&NQ)||!arith(p->right->ntyp->flags&NQ)){
  217.             if((p->left->ntyp->flags&NQ)!=POINTER||(p->right->ntyp->flags&NQ)!=POINTER){
  218.                 if(f!=EQUAL&&f!=INEQUAL){
  219.                     error(92);return(0);
  220.                 }else{
  221.                     if(((p->left->ntyp->flags&NQ)!=POINTER||p->right->flags!=CEXPR)&&
  222.                        ((p->right->ntyp->flags&NQ)!=POINTER||p->left->flags!=CEXPR)){
  223.                         error(93);return(0);
  224.                     }else{
  225.                         if(p->left->flags==CEXPR) eval_constn(p->left);
  226.                          else                     eval_constn(p->right);
  227.                         if(!zdeqto(vdouble,d2zd(0.0))||!zleqto(vlong,l2zl(0L))||!zuleqto(vulong,ul2zul(0UL)))
  228.                             {error(40);return(0);}
  229.                     }
  230.                 }
  231.             }else{
  232.                 if(compare_pointers(p->left->ntyp->next,p->right->ntyp->next,NQ)){
  233.                 }else{
  234.                     if(f!=EQUAL&&f!=INEQUAL){error(41);}
  235.                     if((p->left->ntyp->next->flags&NQ)!=VOID&&(p->right->ntyp->next->flags&NQ)!=VOID)
  236.                         {error(41);}
  237.                 }
  238.             }
  239.         }
  240.         if(p->left->flags==CEXPR){
  241.             eval_constn(p->left);
  242.             d1=vdouble;u1=vulong;s1=vlong;c|=1;
  243.             if(p->right->ntyp->flags&UNSIGNED&&!(p->left->ntyp->flags&UNSIGNED)){
  244.                 if(zdleq(d1,zl2zd(l2zl(0)))&&zlleq(s1,l2zl(0))){
  245.                     if(!zdeqto(d1,d2zd(0.0))||!zleqto(s1,l2zl(0L))){
  246.                         error(165);
  247.                     }else{
  248.                         if(f==GREATER||f==LESSEQ) error(165);
  249.                     }
  250.                 }
  251.             }
  252.         }
  253.         if(p->right->flags==CEXPR){
  254.             eval_constn(p->right);
  255.             d2=vdouble;u2=vulong;s2=vlong;c|=2;
  256.             if(p->left->ntyp->flags&UNSIGNED&&!(p->right->ntyp->flags&UNSIGNED)){
  257.                 if(zdleq(d2,zl2zd(l2zl(0)))&&zlleq(s2,l2zl(0))){
  258.                     if(!zdeqto(d2,d2zd(0.0))||!zleqto(s2,l2zl(0L))){
  259.                         error(165);
  260.                     }else{
  261.                         if(f==LESS||f==GREATEREQ) error(165);
  262.                     }
  263.                 }
  264.             }
  265.         }
  266.         p->ntyp=mymalloc(TYPS);
  267.         p->ntyp->flags=INT;
  268.         p->ntyp->next=0;
  269.         if(c==3){
  270.             p->flags=CEXPR;
  271.             t=arith_typ(p->left->ntyp,p->right->ntyp);
  272.             if(!p->left->sidefx) {free_expression(p->left);p->left=0;}
  273.             if(!p->right->sidefx) {free_expression(p->right);p->right=0;}
  274.             if((t->flags&NQ)==FLOAT||(t->flags&NQ)==DOUBLE){
  275.                 if(f==EQUAL) p->val.vint=zdeqto(d1,d2);
  276.                 if(f==INEQUAL) p->val.vint=!zdeqto(d1,d2);
  277.                 if(f==LESSEQ) p->val.vint=zdleq(d1,d2);
  278.                 if(f==GREATER) p->val.vint=!zdleq(d1,d2);
  279.                 if(f==LESS){
  280.                     if(zdleq(d1,d2)&&!zdeqto(d1,d2)) p->val.vint=1;
  281.                      else p->val.vint=0;
  282.                 }
  283.                 if(f==GREATEREQ){
  284.                     if(!zdleq(d1,d2)||zdeqto(d1,d2)) p->val.vint=1;
  285.                      else p->val.vint=0;
  286.                 }
  287.             }else{
  288.                 if(t->flags&UNSIGNED){
  289.                     if(f==EQUAL) p->val.vint=zuleqto(u1,u2);
  290.                     if(f==INEQUAL) p->val.vint=!zuleqto(u1,u2);
  291.                     if(f==LESSEQ) p->val.vint=zulleq(u1,u2);
  292.                     if(f==GREATER) p->val.vint=!zulleq(u1,u2);
  293.                     if(f==LESS){
  294.                         if(zulleq(u1,u2)&&!zuleqto(u1,u2)) p->val.vint=1;
  295.                          else p->val.vint=0;
  296.                     }
  297.                     if(f==GREATEREQ){
  298.                         if(!zulleq(u1,u2)||zuleqto(u1,u2)) p->val.vint=1;
  299.                          else p->val.vint=0;
  300.                     }
  301.                 }else{
  302.                     if(f==EQUAL) p->val.vint=zleqto(s1,s2);
  303.                     if(f==INEQUAL) p->val.vint=!zleqto(s1,s2);
  304.                     if(f==LESSEQ) p->val.vint=zlleq(s1,s2);
  305.                     if(f==GREATER) p->val.vint=!zlleq(s1,s2);
  306.                     if(f==LESS){
  307.                         if(zlleq(s1,s2)&&!zleqto(s1,s2)) p->val.vint=1;
  308.                          else p->val.vint=0;
  309.                     }
  310.                     if(f==GREATEREQ){
  311.                         if(!zlleq(s1,s2)||zleqto(s1,s2)) p->val.vint=1;
  312.                          else p->val.vint=0;
  313.                     }
  314.                 }
  315.             }
  316.             freetyp(t);
  317.         }
  318.         return(ok);
  319.     }
  320.     if(f==ADD||f==SUB||f==MULT||f==DIV||f==MOD||f==LSHIFT||f==RSHIFT||f==PMULT){
  321.         if(!arith(p->left->ntyp->flags&NQ)||!arith(p->right->ntyp->flags&NQ)){
  322.             np new;zlong sz; int type=0;
  323.             if(f!=ADD&&f!=SUB){error(94);return(0);}
  324.             if((p->left->ntyp->flags&NQ)==POINTER){
  325.                 if((p->left->ntyp->next->flags&NQ)==VOID)
  326.                     {error(95);return(0);}
  327.                 if((p->right->ntyp->flags&NQ)==POINTER){
  328.                     if((p->right->ntyp->next->flags&NQ)==VOID)
  329.                         {error(95);return(0);}
  330.                     if(!compare_pointers(p->left->ntyp->next,p->right->ntyp->next,NQ))
  331.                         {error(41);}
  332.                     if(f!=SUB){error(96);return(0);}
  333.                      else {type=3;}
  334.                 }else{
  335.                     if((p->right->ntyp->flags&NQ)>LONG)
  336.                         {error(97,ename[f]);return(0);}
  337.                     if((p->right->ntyp->flags&NQ)<CHAR)
  338.                         {error(97,ename[f]);return(0);}
  339.                     if(p->right->flags!=PMULT&&p->right->flags!=PCEXPR){
  340.                         new=mymalloc(NODES);
  341.                         new->flags=PMULT;
  342.                         new->ntyp=0;
  343.                         new->left=p->right;
  344.                         new->right=mymalloc(NODES);
  345.                         new->right->flags=PCEXPR;
  346.                         new->right->left=new->right->right=0;
  347.                         new->right->ntyp=mymalloc(TYPS);
  348.                         new->right->ntyp->flags=INT;
  349.                         new->right->ntyp->next=0;
  350.                         sz=szof(p->left->ntyp->next);
  351.                         if(zleqto(l2zl(0L),sz)) error(78);
  352.                         new->right->val.vint=zl2zi(sz);
  353.                         p->right=new;
  354.                         ok&=type_expression2(p->right);
  355.                     }
  356.                     type=1;
  357.                 }
  358.             }else{
  359.                 np merk;
  360.                 if((p->right->ntyp->flags&NQ)!=POINTER)
  361.                     {error(98);return(0);}
  362.                 if((p->right->ntyp->next->flags&NQ)==VOID)
  363.                     {error(95);return(0);}
  364.                 if((p->left->ntyp->flags&NQ)>LONG)
  365.                     {error(98);return(0);}
  366.                 if((p->left->ntyp->flags&NQ)<CHAR)
  367.                     {error(98);return(0);}
  368.                 if(p->flags==SUB){error(99);return(0);}
  369.                 if(p->left->flags!=PMULT&&p->left->flags!=PCEXPR){
  370.                     new=mymalloc(NODES);
  371.                     new->flags=PMULT;
  372.                     new->ntyp=0;
  373.                     new->left=p->left;
  374.                     new->right=mymalloc(NODES);
  375.                     new->right->flags=PCEXPR;
  376.                     new->right->left=new->right->right=0;
  377.                     new->right->ntyp=mymalloc(TYPS);
  378.                     new->right->ntyp->flags=INT;
  379.                     new->right->ntyp->next=0;
  380.                     sz=szof(p->right->ntyp->next);
  381.                     if(zleqto(l2zl(0L),sz)) error(78);
  382.                     new->right->val.vint=zl2zi(sz);
  383.                     p->left=new;
  384.                     ok&=type_expression2(p->left);
  385.                 }
  386.                 type=2;
  387.                 merk=p->left;p->left=p->right;p->right=merk;
  388.             }
  389.             if(type==0){ierror(0);return(0);}
  390.             else{
  391.                 if(type==3){
  392.                     p->ntyp=mymalloc(TYPS);
  393.                     p->ntyp->next=0;p->ntyp->flags=INT;
  394.                 }else{
  395.                     /*if(type==1)*/ p->ntyp=clone_typ(p->left->ntyp);
  396.                     /* else       p->ntyp=clone_typ(p->right->ntyp);*/
  397.                     /*  Abfrage wegen Vertauschen der Knoten unnoetig   */
  398.                 }
  399.             }
  400.         }else{
  401.             p->ntyp=arith_typ(p->left->ntyp,p->right->ntyp);
  402.             if((p->ntyp->flags&NQ)>LONG&&(f==MOD||f==LSHIFT||f==RSHIFT))
  403.                 {error(101);ok=0;}
  404.             /*  Typerweiterungen fuer SHIFTS korrigieren    */
  405.             if((f==LSHIFT||f==RSHIFT)&&(p->ntyp->flags&NQ)==LONG&&(p->left->ntyp->flags&NQ)<LONG)
  406.                 {p->ntyp->flags&=~NQ;p->ntyp->flags|=INT;}
  407.         }
  408.         /*  fuegt &a+x zusammen, noch sub und left<->right machen   */
  409.         /*  Bei CEXPR statt PCEXPR auch machen?                     */
  410.         if((p->flags==ADD||p->flags==SUB)){
  411.             np m,c=0,a=0;
  412.             if(p->left->flags==PCEXPR&&p->flags==ADD) c=p->left;
  413.             if(p->right->flags==PCEXPR) c=p->right;
  414.             if(p->left->flags==ADDRESS||p->left->flags==ADDRESSA||p->left->flags==ADDRESSS) a=p->left;
  415.             if(p->right->flags==ADDRESS||p->right->flags==ADDRESSA||p->right->flags==ADDRESSS) a=p->right;
  416.             if(c&&a){
  417.                 m=a->left;
  418.                 /*  kann man das hier so machen oder muss man da mehr testen ?  */
  419.                 while(m->flags==FIRSTELEMENT||m->flags==ADDRESS||m->flags==ADDRESSA||m->flags==ADDRESSS) m=m->left;
  420.                 if(m->flags==IDENTIFIER){
  421.                     if(DEBUG&1) printf("&a+x with %s combined\n",ename[p->left->flags]);
  422.                     eval_const(&c->val,c->ntyp->flags);
  423.                     if(p->flags==ADD) m->val.vlong=zuladd(m->val.vlong,vlong);
  424.                      else m->val.vlong=zlsub(m->val.vlong,vlong);
  425.                     vlong=szof(m->ntyp);
  426.                     if(!zleqto(vlong,l2zl(0L))&&zulleq(vlong,m->val.vlong)){
  427.                         if(zuleqto(vlong,m->val.vlong))
  428.                             error(79);
  429.                         else
  430.                             error(80);
  431.                     }
  432.                     vlong=l2zl(0L);
  433.                     if(!zleqto(m->val.vlong,l2zl(0L))&&zulleq(m->val.vlong,vlong)) error(80);
  434.                     free_expression(c);
  435.                     if(p->ntyp) freetyp(p->ntyp);
  436.                     *p=*a;
  437.                     free(a);
  438.                     return(type_expression2(p));
  439.                 }
  440.             }
  441.         }
  442.         if(!mopt){
  443.             if(!alg_opt(p)) ierror(0);
  444.         }
  445.         return(ok);
  446.     }
  447.     if(f==CAST){
  448.         int from=p->left->ntyp->flags&NQ,to=p->ntyp->flags&NQ;
  449.         if(to==VOID) return(ok);
  450.         if(from==VOID)
  451.             {error(102);return(0);}
  452.         if((!arith(to)||!arith(from))&&
  453.            (to!=POINTER||from!=POINTER)){
  454.             if(to==POINTER){
  455.                 if(from<=LONG){
  456.                     if(!zlleq(sizetab[from],sizetab[POINTER])){
  457.                         error(103);return(0);
  458.                     }
  459.                 }else{
  460.                     error(104);return(0);
  461.                 }
  462.             }else{
  463.                 if(from!=POINTER)
  464.                     {error(105);return(0);}
  465.                 if(to<=LONG){
  466.                     if(!zlleq(sizetab[POINTER],sizetab[to])){
  467.                         error(106);return(0);
  468.                     }
  469.                 }else{
  470.                     error(104);return(0);
  471.                 }
  472.             }
  473.         }
  474.         if(from<=LONG&&to<=LONG&&!zlleq(sizetab[from],sizetab[to])&&p->left->flags!=CEXPR) error(166);
  475.         if(to==POINTER&&from==POINTER&&!zlleq(falign(p->ntyp->next),falign(p->left->ntyp->next)))
  476.             error(167);
  477.         if(p->left->flags==CEXPR){
  478.             eval_constn(p->left);
  479.             if((p->ntyp->flags&NQ)==POINTER)
  480.                 if(!zuleqto(vulong,ul2zul(0UL))||!zleqto(vlong,l2zl(0L))||!zdeqto(vdouble,d2zd(0.0)))
  481.                     error(81);
  482.             insert_const(p);
  483.             p->flags=CEXPR;
  484.             if(!p->left->sidefx) {free_expression(p->left);p->left=0;}
  485.         }
  486.         return(ok);
  487.     }
  488.     if(f==MINUS||f==KOMPLEMENT||f==NEGATION){
  489.         if(!arith(p->left->ntyp->flags&NQ)){
  490.             if(f!=NEGATION){error(107);return(0);
  491.             }else{
  492.                 if((p->left->ntyp->flags&NQ)!=POINTER)
  493.                     {error(108);return(0);}
  494.             }
  495.         }
  496.         if(f==KOMPLEMENT&&(p->left->ntyp->flags&NQ)>LONG)
  497.             {error(109);return(0);}
  498.         if(f==NEGATION){
  499.             p->ntyp=mymalloc(TYPS);
  500.             p->ntyp->next=0;
  501.             p->ntyp->flags=INT;
  502.         }else{
  503.             if(!p->left->ntyp) ierror(0);
  504.             p->ntyp=clone_typ(p->left->ntyp);
  505.             if((p->ntyp->flags&NQ)<=LONG) p->ntyp->flags=int_erw(p->ntyp->flags);
  506.         }
  507.         if(p->left->flags==CEXPR){
  508.             eval_constn(p->left);
  509.             if(f==KOMPLEMENT){vlong=zlkompl(vlong);vulong=zlkompl(vulong);
  510.                               vint=zl2zi(vlong);vuint=zul2zui(vulong);}
  511.             if(f==MINUS){vdouble=zdsub(d2zd(0.0),vdouble);vfloat=zd2zf(vdouble);
  512.                          vulong=zulsub(ul2zul(0UL),vulong);vuint=zul2zui(vulong);
  513.                          vlong=zlsub(l2zl(0L),vlong);vint=zl2zi(vlong);}
  514.             if(f==NEGATION){if(zdeqto(vdouble,d2zd(0.0))&&zuleqto(vulong,ul2zul(0UL))&&zleqto(vlong,l2zl(0L)))
  515.                 vlong=l2zl(1L); else vlong=l2zl(0L);
  516.                 vint=zl2zi(vlong);
  517.             }
  518.             insert_const(p);
  519.             p->flags=CEXPR;
  520.             if(!p->left->sidefx&&p->left) {free_expression(p->left);p->left=0;}
  521.         }
  522.         return(ok);
  523.     }
  524.     if(f==CONTENT){
  525.         if((p->left->ntyp->flags&NQ)!=POINTER)
  526.             {error(111);return(0);}
  527.         if((p->left->ntyp->next->flags&NQ)!=ARRAY&&type_uncomplete(p->left->ntyp->next))
  528.             {error(112);return(0);}
  529.         p->ntyp=clone_typ(p->left->ntyp->next);
  530.         if((p->ntyp->flags&NQ)!=ARRAY) p->lvalue=1;
  531.         if(p->left->flags==ADDRESS&&zuleqto(p->left->val.vulong,ul2zul(0UL))){
  532.         /*  *&x durch x ersetzen                                */
  533.             np merk;
  534.             merk=p->left;
  535.             if(p->ntyp) freetyp(p->ntyp);
  536.             if(p->left->ntyp) freetyp(p->left->ntyp);
  537.             *p=*p->left->left;
  538.             free(merk->left);
  539.             free(merk);
  540.             return(ok);
  541.         }
  542.         /*  *&ax durch firstelement-of(x) ersetzen  */
  543.         if(p->left->flags==ADDRESSA||p->left->flags==ADDRESSS){
  544.             np merk;
  545.             if(DEBUG&1) printf("substitutet * and %s with FIRSTELEMENT\n",ename[p->left->flags]);
  546.             p->flags=FIRSTELEMENT;
  547.             p->lvalue=1;    /*  evtl. hier erst Abfrage ?   */
  548.             merk=p->left;
  549.             p->left=merk->left;
  550.             p->right=merk->right;
  551.             if(merk->ntyp) freetyp(merk->ntyp);
  552.             free(merk);
  553.         }
  554.         return(ok);
  555.     }
  556.     if(f==FIRSTELEMENT){
  557. /*        if((p->left->ntyp->flags&NQ)!=ARRAY)
  558.             {ierror(0);return(0);}*/
  559.         if((p->left->ntyp->flags&NQ)==ARRAY) p->ntyp=clone_typ(p->left->ntyp->next);
  560.          else{
  561.             int i,n=-1;
  562.             for(i=0;i<p->left->ntyp->exact->count;i++)
  563.                 if(!strcmp((*p->left->ntyp->exact->sl)[i].identifier,p->right->identifier)) n=i;
  564.             if(n<0){ierror(0);return(0);}
  565.             p->ntyp=clone_typ((*p->left->ntyp->exact->sl)[n].styp);
  566.         }
  567.         p->lvalue=1;    /*  hier noch genauer testen ?  */
  568.         return(ok);
  569.     }
  570.     if(f==ADDRESS){
  571.         if((p->left->ntyp->flags&NQ)!=FUNKT&&(p->left->ntyp->flags&NQ)!=ARRAY){
  572.             if(!p->left->lvalue){error(115);return(0);}
  573.             if(p->left->flags==IDENTIFIER){
  574.                 struct Var *v;
  575.                 v=find_var(p->left->identifier,0);
  576.                 if(!v){error(116,p->left->identifier);return(0);}
  577.                 if(v->storage_class==REGISTER)
  578.                     {error(117);return(0);}
  579.             }
  580.         }
  581.         p->ntyp=mymalloc(TYPS);
  582.         p->ntyp->flags=POINTER;
  583.         p->ntyp->next=clone_typ(p->left->ntyp);
  584.         return(ok);
  585.     }
  586.     if(f==ADDRESSA){
  587.         p->ntyp=clone_typ(p->left->ntyp);
  588.         p->ntyp->flags=POINTER;
  589.         return(ok);
  590.     }
  591.     if(f==ADDRESSS){
  592.         int i,n=-1;
  593.         for(i=0;i<p->left->ntyp->exact->count;i++)
  594.             if(!strcmp((*p->left->ntyp->exact->sl)[i].identifier,p->right->identifier)) n=i;
  595.         if(n<0){ierror(0);return(0);}
  596.         p->ntyp=mymalloc(TYPS);
  597.         p->ntyp->flags=POINTER;
  598.         if(!p->left->ntyp) ierror(0);
  599.         if(!p->left->ntyp->exact) ierror(0);
  600.         if(!(*p->left->ntyp->exact->sl)[n].styp) ierror(0);
  601.         p->ntyp->next=clone_typ((*p->left->ntyp->exact->sl)[n].styp);
  602.         return(ok);
  603.     }
  604.     if(f==DSTRUCT){
  605.     /*  hier kann man bei unions einiges schneller/einfacher machen */
  606.         int i=0,f;struct Typ *t;np new;zlong offset=l2zl(0L),al;
  607.         if((p->left->ntyp->flags&NQ)!=STRUCT&&(p->left->ntyp->flags&NQ)!=UNION)
  608.             {error(8);return(0);}
  609.         if(type_uncomplete(p->left->ntyp)){error(11);return(0);}
  610.         if(p->right->flags!=MEMBER)
  611.             {ierror(0);return(0);}
  612.         while(i<p->left->ntyp->exact->count&&strcmp((*p->left->ntyp->exact->sl)[i].identifier,p->right->identifier)){
  613.             t=(*p->left->ntyp->exact->sl)[i].styp;
  614.         al=falign(t);
  615.             offset=zlmult(zldiv(zladd(offset,zlsub(al,l2zl(1L))),al),al);
  616.             offset=zladd(offset,szof(t));
  617.             i++;
  618.         }
  619.         if(i>=p->left->ntyp->exact->count) {error(23,p->right->identifier);return(0);}
  620.  
  621.         t=(*p->left->ntyp->exact->sl)[i].styp;
  622.         al=falign(t);
  623.         offset=zlmult(zldiv(zladd(offset,zlsub(al,l2zl(1L))),al),al);
  624.         if((p->left->ntyp->flags&NQ)==UNION) offset=l2zl(0L);
  625.         p->flags=CONTENT;if(p->ntyp) {freetyp(p->ntyp);p->ntyp=0;}
  626.         new=mymalloc(NODES);
  627.         new->flags=ADD;
  628.         new->ntyp=0;
  629.         new->right=mymalloc(NODES);
  630.         new->right->left=new->right->right=0;
  631.         new->right->flags=PCEXPR;
  632.         new->right->ntyp=mymalloc(TYPS);
  633.         if(MINADDI2P<=INT&&zulleq(zl2zul(offset),t_max[INT])){
  634.           new->right->ntyp->flags=INT;
  635.           new->right->ntyp->next=0;
  636.           new->right->val.vint=zl2zi(offset);
  637.         }else{
  638.           new->right->ntyp->flags=LONG;
  639.           new->right->ntyp->next=0;
  640.           new->right->val.vlong=offset;
  641.         }
  642.         new->left=mymalloc(NODES);
  643.         new->left->flags=ADDRESSS;
  644.         new->left->left=p->left;
  645.         new->left->right=p->right;
  646.         new->left->ntyp=0;
  647.         p->left=new;p->right=0;
  648.  
  649.         return(type_expression2(p));
  650.     }
  651.     if(f==PREINC||f==POSTINC||f==PREDEC||f==POSTDEC){
  652.         if(!p->left->lvalue){error(86);return(0);}
  653.         if(p->left->ntyp->flags&CONST){error(87);return(0);}
  654.         if(!arith(p->left->ntyp->flags&NQ)){
  655.             if((p->left->ntyp->flags&NQ)!=POINTER){
  656.                 error(24);return(0);
  657.             }else{
  658.                 if((p->left->ntyp->next->flags&NQ)==VOID)
  659.                     {error(95);return(0);}
  660.             }
  661.         }
  662.         p->ntyp=clone_typ(p->left->ntyp);
  663.         p->sidefx=1;
  664.         return(ok);
  665.     }
  666.     if(f==CALL){
  667.         struct argument_list *al;int i,flags=0;char *s=0;
  668.         struct struct_declaration *sd;
  669.         al=p->alist;
  670.         if((p->left->ntyp->flags&NQ)!=POINTER||(p->left->ntyp->next->flags&NQ)!=FUNKT)
  671.             {error(26);return(0);}
  672.         if(ok&&p->left->left&&p->left->left->flags==IDENTIFIER&&p->left->left->o.v->storage_class==EXTERN){
  673.             s=p->left->left->o.v->identifier;
  674.             flags=p->left->left->o.v->flags;
  675.         }
  676.         sd=p->left->ntyp->next->exact;
  677.         if(!sd){ierror(0);return(0);}
  678.         if(sd->count==0){
  679.             error(162);
  680.             if(s){
  681.                 if(!strcmp(s,"printf")||!strcmp(s,"fprintf")||!strcmp(s,"sprintf")||
  682.                    !strcmp(s,"scanf")|| !strcmp(s,"fscanf")|| !strcmp(s,"sscanf"))
  683.                     error(213);
  684.             }
  685.         }
  686.         while(al){
  687.             if(!al->arg) ierror(0);
  688.             if(!type_expression2(al->arg)) return(0);
  689.             al->arg=makepointer(al->arg);
  690.             if(type_uncomplete(al->arg->ntyp)) error(39);
  691.             al=al->next;
  692.         }
  693.         p->sidefx=1;
  694.         p->ntyp=clone_typ(p->left->ntyp->next->next);
  695.         i=0;al=p->alist;
  696.         while(al){
  697.             if(i>=sd->count) return(ok);
  698.             if(!(*sd->sl)[i].styp) return(ok); /* nur Bezeichner, aber kein Typ im Prototype */
  699.             if(!test_assignment((*sd->sl)[i].styp,al->arg)) return(0);
  700.             if(i==sd->count-1&&(flags&(PRINTFLIKE|SCANFLIKE))){
  701.                 if(al->arg->left&&al->arg->left->flags==STRING){
  702.                 /*  Argumente anhand des Formatstrings ueberpruefen */
  703.                     struct const_list *cl=al->arg->left->cl;
  704.                     int fused=0;
  705.                     al=al->next;
  706.                     while(cl&&cl->other){
  707.                         int c,fflags=' ',at;
  708.                         struct Typ *t;
  709.                         c=(int)zul2zl(zuc2zul(cl->other->val.vchar));
  710.                         cl=cl->next;
  711.                         if(c==0){
  712.                             if(cl) error(215);
  713.                             break;
  714.                         }
  715.                         if(c!='%') continue;
  716.                         if(!cl){error(214);return(ok);}
  717.                         c=(int)zul2zl(zuc2zul(cl->other->val.vchar));
  718.                         cl=cl->next;
  719.                         while(isdigit((unsigned char)c)||
  720.                               c=='-'||c=='+'||c==' '||c=='#'||c=='.'||
  721.                               c=='h'||c=='l'||c=='L'||c=='*'){
  722.                             fused|=3;
  723.                 if(c=='*'&&(flags&PRINTFLIKE)){
  724.                   if(!al) {error(214);return(ok);}
  725.                     at=al->arg->ntyp->flags&NQ;
  726.                 al=al->next;
  727.                 if(at>INT) {error(214);return(ok);}
  728.                 }
  729.                             if((fflags!='*'||(flags&PRINTFLIKE))&&(c=='h'||c=='l'||c=='L'||c=='*'))
  730.                                 fflags=c;
  731.                             c=(int)zul2zl(zuc2zul(cl->other->val.vchar));
  732.                             cl=cl->next;
  733.                             if(!cl){error(214);return(ok);}
  734.                         }
  735.                         if(DEBUG&1) printf("format=%c%c\n",fflags,c);
  736.                         if(fflags=='*'&&(flags&SCANFLIKE)) continue;
  737.             if(c!='%'){
  738.               if(!al){error(214);return(ok);}
  739.               t=al->arg->ntyp;
  740.               if(DEBUG&1){ prd(stdout,t);printf("\n");}
  741.               if((flags&SCANFLIKE)){
  742.                             if((t->flags&NQ)!=POINTER){error(214);return(ok);}
  743.                             t=t->next;
  744.               }
  745.               at=t->flags&NU;
  746.             }
  747.                         if(flags&PRINTFLIKE){
  748.                             switch(c){
  749.                 case '%':
  750.                     fused|=1;
  751.                     break;
  752.                             case 'o':
  753.                             case 'x':
  754.                             case 'X':
  755.                             case 'c':
  756.                                 at&=NQ;     /*  fall through    */
  757.                             case 'i':
  758.                             case 'd':
  759.                                 fused|=1;
  760.                                 if(at==LONG&&fflags!='l'){error(214);return(ok);}
  761.                                 if(fflags=='l'&&at!=LONG){error(214);return(ok);}
  762.                                 if(at<CHAR||at>LONG){error(214);return(ok);}
  763.                                 break;
  764.                             case 'u':
  765.                                 fused|=1;
  766.                                 if(al->arg->flags==CEXPR) at|=UNSIGNED;
  767.                                 if(at==(UNSIGNED|LONG)&&fflags!='l'){error(214);return(ok);}
  768.                                 if(fflags=='l'&&at!=(UNSIGNED|LONG)){error(214);return(ok);}
  769.                                 if(at<(UNSIGNED|CHAR)||at>(UNSIGNED|LONG)){error(214);return(ok);}
  770.                                 break;
  771.                             case 's':
  772.                                 fused|=1;
  773.                                 if(at!=POINTER||(t->next->flags&NQ)!=CHAR){error(214);return(ok);}
  774.                                 break;
  775.                             case 'f':
  776.                             case 'e':
  777.                             case 'E':
  778.                             case 'g':
  779.                             case 'G':
  780.                                 fused|=7;
  781.                                 if(at!=FLOAT&&at!=DOUBLE){error(214);return(ok);}
  782.                                 break;
  783.                             case 'p':
  784.                                 fused|=3;
  785.                                 if(at!=POINTER||(t->next->flags)!=VOID){error(214);return(ok);}
  786.                                 break;
  787.                             case 'n':
  788.                                 fused|=3;
  789.                                 if(at!=POINTER){error(214);return(ok);}
  790.                                 at=t->next->flags&NU;
  791.                                 if(fflags=='h'&&at!=SHORT){error(214);return(ok);}
  792.                                 if(fflags==' '&&at!=INT){error(214);return(ok);}
  793.                                 if(fflags=='l'&&at!=LONG){error(214);return(ok);}
  794.                                 break;
  795.                             default:
  796.                                 error(214);return(ok);
  797.                             }
  798.                         }else{
  799.                             switch(c){
  800.                 case '%':
  801.                     fused|=1;
  802.                 break;
  803.                             case '[':
  804.                                 fused|=3;
  805.                                 do{
  806.                                     c=(int)zul2zl(zuc2zul(cl->other->val.vchar));
  807.                                     cl=cl->next;
  808.                                     if(!cl){error(214);return(ok);}
  809.                                 }while(c!=']');     /*  fall through    */
  810.                             case 's':
  811.                             case 'c':
  812.                                 fused|=1;
  813.                                 if((at&NQ)!=CHAR){error(214);return(ok);}
  814.                                 break;
  815.                             case 'n':
  816.                                 fused|=3;       /*  fall through    */
  817.                             case 'd':
  818.                             case 'i':
  819.                             case 'o':
  820.                             case 'x':
  821.                                 fused|=1;
  822.                                 if(fflags=='h'&&at!=SHORT){error(214);return(ok);}
  823.                                 if(fflags==' '&&at!=INT){error(214);return(ok);}
  824.                                 if(fflags=='l'&&at!=LONG){error(214);return(ok);}
  825.                                 break;
  826.                             case 'u':
  827.                                 fused|=1;
  828.                                 if(fflags=='h'&&at!=(UNSIGNED|SHORT)){error(214);return(ok);}
  829.                                 if(fflags==' '&&at!=(UNSIGNED|INT)){error(214);return(ok);}
  830.                                 if(fflags=='l'&&at!=(UNSIGNED|LONG)){error(214);return(ok);}
  831.                                 break;
  832.                             case 'e':
  833.                             case 'f':
  834.                             case 'g':
  835.                                 fused|=7;
  836.                                 if(fflags==' '&&at!=FLOAT){error(214);return(ok);}
  837.                                 if(fflags=='l'&&at!=DOUBLE){error(214);return(ok);}
  838.                                 if(fflags=='L'&&at!=DOUBLE){error(214);return(ok);}
  839.                                 break;
  840.                             case 'p':
  841.                                 fused|=3;
  842.                                 if(at!=POINTER||(t->next->flags&NQ)!=VOID){error(214);return(ok);}
  843.                                 break;
  844.                             default:
  845.                                 error(214);return(ok);
  846.                             }
  847.                         }
  848.                         if(c!='%') al=al->next;
  849.                     }
  850.                     if(al){ error(214);return(ok);} /* zu viele */
  851.                     if(DEBUG&1) printf("fused=%d\n",fused);
  852.                     if(fused!=7&&s){
  853.                     /*  Wenn kein Format benutzt wird, kann man printf, */
  854.                     /*  scanf etc. durch aehnliches ersetzen.           */
  855.                         struct Var *v;char repl[MAXI+6]="__v";
  856.                         if(fused==3) fused=2;
  857.                         repl[3]=fused+'0';repl[4]=0;
  858.                         strcat(repl,s);
  859.                         if(DEBUG&1) printf("repl=%s\n",repl);
  860.                         while(fused<=2){
  861.                             v=find_var(repl,0);
  862.                             if(v&&v->storage_class==EXTERN){
  863.                                 p->left->left->o.v=v;
  864.                                 break;
  865.                             }
  866.                             fused++;repl[3]++;
  867.                         }
  868.                     }
  869.                     return(ok);
  870.                 }
  871.             }
  872.             i++;al=al->next;
  873.         }
  874.         if(i>=sd->count) return(ok);
  875.         if((*sd->sl)[i].styp&&((*sd->sl)[i].styp->flags&NQ)!=VOID){error(83);/*printf("sd->count=%d\n",sd->count);*/}
  876.         return(ok);
  877.     }
  878.     if(f==COND){
  879.         if(!arith(p->left->ntyp->flags&NQ)&&(p->left->ntyp->flags&NQ)!=POINTER){
  880.             error(29);
  881.             return(0);
  882.         }
  883.         if(p->left->flags==CEXPR&&!p->left->sidefx){
  884.             int null;np merk;
  885.             if(DEBUG&1) printf("constant conditional-expression simplified\n");
  886.             eval_constn(p->left);
  887.             if(zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))&&zdeqto(vdouble,d2zd(0.0))) null=1; else null=0;
  888.             free_expression(p->left);
  889.             merk=p->right;
  890.             if(null){
  891.                 free_expression(p->right->left);
  892.                 *p=*p->right->right;
  893.             }else{
  894.                 free_expression(p->right->right);
  895.                 *p=*p->right->left;
  896.             }
  897.             if(merk->ntyp) freetyp(merk->ntyp);
  898.             free(merk);
  899.             return(1);
  900.         }
  901.         p->ntyp=clone_typ(p->right->ntyp);
  902.         return(1);
  903.     }
  904.     if(f==COLON){
  905.         /*  Hier fehlt noch korrekte Behandlung der Typattribute    */
  906.         if(arith(p->left->ntyp->flags&NQ)&&arith(p->right->ntyp->flags&NQ)){
  907.             p->ntyp=arith_typ(p->left->ntyp,p->right->ntyp);
  908.             return(1);
  909.         }
  910.         if(compare_pointers(p->left->ntyp,p->right->ntyp,NQ)){
  911.             p->ntyp=clone_typ(p->left->ntyp);
  912.             return(1);
  913.         }
  914.         if((p->left->ntyp->flags&NQ)==POINTER&&(p->right->ntyp->flags&NQ)==POINTER){
  915.             if((p->left->ntyp->next->flags&NQ)==VOID){
  916.                 p->ntyp=clone_typ(p->left->ntyp);
  917.                 return(1);
  918.             }
  919.             if((p->right->ntyp->next->flags&NQ)==VOID){
  920.                 p->ntyp=clone_typ(p->right->ntyp);
  921.                 return(1);
  922.             }
  923.         }
  924.         if((p->left->ntyp->flags&NQ)==POINTER&&p->right->flags==CEXPR){
  925.             eval_constn(p->right);
  926.             if(zleqto(vlong,l2zl(0L))&&zuleqto(ul2zul(0UL),vulong)&&zdeqto(d2zd(0.0),vdouble)){
  927.                 p->ntyp=clone_typ(p->left->ntyp);
  928.                 return(1);
  929.             }
  930.         }
  931.         if((p->right->ntyp->flags&NQ)==POINTER&&p->left->flags==CEXPR){
  932.             eval_constn(p->left);
  933.             if(zleqto(l2zl(0L),vlong)&&zuleqto(ul2zul(0UL),vulong)&&zdeqto(d2zd(0.0),vdouble)){
  934.                 p->ntyp=clone_typ(p->right->ntyp);
  935.                 return(1);
  936.             }
  937.         }
  938.         error(31);
  939.         return(0);
  940.     }
  941.     if(f) printf("type_testing fuer diesen Operator (%d) noch nicht implementiert\n",f);
  942.     return(0);
  943. }
  944.  
  945. np makepointer(np p)
  946. /*  Fuehrt automatische Zeigererzeugung fuer Baumwurzel durch   */
  947. /*  Durch mehrmaligen Aufruf von type_expression() ineffizient  */
  948. {
  949.     struct struct_declaration *sd;
  950.     if((p->ntyp->flags&NQ)==ARRAY||(p->ntyp->flags&NQ)==FUNKT){
  951.         np new=mymalloc(NODES);
  952.         if((p->ntyp->flags&NQ)==ARRAY){
  953.             new->flags=ADDRESSA;
  954.             new->ntyp=clone_typ(p->ntyp);
  955.             new->ntyp->flags=POINTER;
  956. /*            new->ntyp=0;*/
  957.         }else{
  958.             new->flags=ADDRESS;
  959.             new->ntyp=mymalloc(TYPS);
  960.             new->ntyp->flags=POINTER;
  961.             new->ntyp->next=clone_typ(p->ntyp);
  962. /*            new->ntyp=0;*/
  963.         }
  964.         new->left=p;
  965.         new->right=0;
  966.         new->lvalue=0;  /* immer korrekt ?  */
  967.         new->sidefx=p->sidefx;
  968. /*        type_expression(new);*/
  969.         return(new);
  970.     }else return(p);
  971. }
  972. int alg_opt(np p)
  973. /*  fuehrt algebraische Vereinfachungen durch                   */
  974. /*  hier noch genau testen, was ANSI-gemaess erlaubt ist etc.   */
  975. /*  v.a. Floating-Point ist evtl. kritisch                      */
  976. {
  977.     int c=0,f,komm,null1,null2,eins1,eins2;np merk;
  978.     zdouble d1,d2;zulong u1,u2;zlong s1,s2;
  979.     f=p->flags;
  980.     /*  kommutativ? */
  981.     if(f==ADD||f==MULT||f==PMULT||(f>=OR&&f<=AND)) komm=1; else komm=0;
  982.     /*  Berechnet Wert, wenn beides Konstanten sind     */
  983.     if(p->left->flags==CEXPR||p->left->flags==PCEXPR){
  984.         eval_constn(p->left);
  985.         d1=vdouble;u1=vulong;s1=vlong;c|=1;
  986.     }
  987.     if(p->right->flags==CEXPR||p->right->flags==PCEXPR){
  988.         eval_constn(p->right);
  989.         d2=vdouble;u2=vulong;s2=vlong;c|=2;
  990.     }
  991.     if(c==3){
  992.         p->flags=CEXPR;
  993.         if(DEBUG&1) printf("did simple constant folding\n");
  994.         if(!p->left->sidefx) {free_expression(p->left);p->left=0;}
  995.         if(!p->right->sidefx) {free_expression(p->right);p->right=0;}
  996.         if(f==AND){
  997.             vulong=zuland(u1,u2);
  998.             vlong=zland(s1,s2);
  999.         }
  1000.         if(f==OR){
  1001.             vulong=zulor(u1,u2);
  1002.             vlong=zlor(s1,s2);
  1003.         }
  1004.         if(f==XOR){
  1005.             vulong=zulxor(u1,u2);
  1006.             vlong=zlxor(s1,s2);
  1007.         }
  1008.         if(f==ADD){
  1009.             vulong=zuladd(u1,u2);
  1010.             vlong=zladd(s1,s2);
  1011.             vdouble=zdadd(d1,d2);
  1012.         }
  1013.         if(f==SUB){
  1014.             vulong=zulsub(u1,u2);
  1015.             vlong=zlsub(s1,s2);
  1016.             vdouble=zdsub(d1,d2);
  1017.         }
  1018.         if(f==MULT||f==PMULT){
  1019.             vulong=zulmult(u1,u2);
  1020.             vlong=zlmult(s1,s2);
  1021.             vdouble=zdmult(d1,d2);
  1022.             if(f==PMULT) p->flags=PCEXPR;
  1023.         }
  1024.         if(f==DIV){
  1025.             if(zleqto(l2zl(0L),s2)&&zuleqto(ul2zul(0UL),u2)&&zdeqto(d2zd(0.0),d2)){
  1026.                 error(84);
  1027.                 vlong=l2zl(0L);vulong=zl2zul(vlong);vdouble=zl2zd(vlong);
  1028.             }else{
  1029.                 if(!zuleqto(ul2zul(0UL),u2)) vulong=zuldiv(u1,u2);
  1030.                 if(!zleqto(l2zl(0L),s2)) vlong=zldiv(s1,s2);
  1031.                 if(!zdeqto(d2zd(0.0),d2)) vdouble=zddiv(d1,d2);
  1032.             }
  1033.         }
  1034.         if(f==MOD){
  1035.             if(zleqto(l2zl(0L),s2)&&zuleqto(ul2zul(0UL),u2)){
  1036.                 error(84);
  1037.                 vlong=l2zl(0L);vulong=zl2zul(vlong);
  1038.             }else{
  1039.                 if(!zuleqto(ul2zul(0UL),u2)) vulong=zulmod(u1,u2);
  1040.                 if(!zleqto(l2zl(0L),s2)) vlong=zlmod(s1,s2);
  1041.             }
  1042.         }
  1043.         if(f==LSHIFT){
  1044.             vulong=zullshift(u1,u2);
  1045.             vlong=zllshift(s1,s2);
  1046.         }
  1047.         if(f==RSHIFT){
  1048.             vulong=zulrshift(u1,u2);
  1049.             vlong=zlrshift(s1,s2);
  1050.         }
  1051.         vuint=zul2zui(vulong);vint=zl2zi(vlong);vfloat=zd2zf(vdouble);
  1052.         insert_const(p);
  1053.         return(1);
  1054.     }
  1055.     /*  Konstanten nach rechts, wenn moeglich       */
  1056.     if(c==1&&komm){
  1057.         if(DEBUG&1) printf("exchanged commutative constant operand\n");
  1058.         merk=p->left;p->left=p->right;p->right=merk;
  1059.         c=2;
  1060.         d2=d1;u2=u1;s2=s1;
  1061.     }
  1062.     /*  Vertauscht die Knoten, um Konstanten                */
  1063.     /*  besser zusammenzufassen (bei allen Type erlaubt?)   */
  1064.     /*  Hier muss noch einiges kontrolliert werden          */
  1065.     if(komm&&c==2&&p->flags==p->left->flags&&((p->ntyp->flags&NQ)<=LONG||c_flags[21]&USEDFLAG)){
  1066.         if(p->left->right->flags==CEXPR||p->left->right->flags==PCEXPR){
  1067.             np merk;
  1068.             merk=p->right;p->right=p->left->left;p->left->left=merk;
  1069.             if(DEBUG&1) printf("Vertausche Add-Nodes\n");
  1070.             return(type_expression(p));
  1071.         }
  1072.     }
  1073.     null1=null2=eins1=eins2=0;
  1074.     if(c&1){
  1075.       if(zdeqto(d1,d2zd(0.0))&&zuleqto(u1,ul2zul(0UL))&&zleqto(s1,l2zl(0L))) null1=1;   
  1076.       if(zdeqto(d1,d2zd(1.0))&&zuleqto(u1,ul2zul(1UL))&&zleqto(s1,l2zl(1L))) eins1=1;
  1077.       if(!(p->ntyp->flags&UNSIGNED)&&zdeqto(d1,d2zd(-1.0))&&zleqto(s1,l2zl(-1L))) eins1=-1;
  1078.     }
  1079.     if(c&2){
  1080.       if(zdeqto(d2,d2zd(0.0))&&zuleqto(u2,ul2zul(0UL))&&zleqto(s2,l2zl(0L))) null2=1; 
  1081.       if(zdeqto(d2,d2zd(1.0))&&zuleqto(u2,ul2zul(1UL))&&zleqto(s2,l2zl(1L))) eins2=1; 
  1082.       if(!(p->ntyp->flags&UNSIGNED)&&zdeqto(d2,d2zd(-1.0))&&zleqto(s2,l2zl(-1L))) eins2=-1;
  1083.     }
  1084.     if(c==2){
  1085.         /*  a+0=a-0=a^0=a>>0=a<<0=a*1=a/1=a   */
  1086.         if(((eins2==1&&(f==MULT||f==PMULT||f==DIV))||(null2&&(f==ADD||f==SUB||f==OR||f==XOR||f==LSHIFT||f==RSHIFT)))&&!p->right->sidefx){
  1087.             if(DEBUG&1){if(f==MULT||f==PMULT||f==DIV) printf("a*/1->a\n"); else printf("a+-^0->a\n");}
  1088.             free_expression(p->right);
  1089.             merk=p->left;
  1090.             *p=*p->left;
  1091. /*            freetyp(merk->ntyp);  das war Fehler  */
  1092.             free(merk);
  1093.             return(type_expression(p));
  1094.         }
  1095.         /*  a*0=0   */
  1096.         if(null2&&(f==MULT||f==PMULT||f==AND||f==DIV||f==MOD)){
  1097.             if(DEBUG&1) printf("a*&/%%0->0\n");
  1098.             if(null2&&(f==DIV||f==MOD)) error(84);
  1099.             if(p->flags==PMULT) p->flags=PCEXPR; else p->flags=CEXPR;
  1100.             /*  hier nur int,long,float,double moeglich, hoffe ich  */
  1101.             vlong=l2zl(0L);vulong=zl2zul(vlong);
  1102.             vint=zl2zi(vlong);vuint=zul2zui(vulong);
  1103.             vdouble=zl2zd(vlong);vfloat=zd2zf(vdouble);
  1104.             insert_const(p);
  1105.             if(!p->left->sidefx){free_expression(p->left);p->left=0;} else make_cexpr(p->left);
  1106.             if(!p->right->sidefx){free_expression(p->right);p->right=0;} else make_cexpr(p->right);
  1107. /*            return(type_expression(p));   */
  1108.             return(1);
  1109.         }
  1110.         if(eins2==-1&&(f==MULT||f==PMULT||f==DIV)&&!p->right->sidefx){
  1111.             if(DEBUG&1) printf("a*/(-1)->-a\n");
  1112.             free_expression(p->right);
  1113.             p->right=0;
  1114.             p->flags=MINUS;
  1115.             return(type_expression(p));
  1116.         }
  1117.     }
  1118.     if(c==1){
  1119.         /*  0-a=-a  */
  1120.         if(f==SUB&&null1&&!p->left->sidefx){
  1121.             if(DEBUG&1) printf("0-a->-a\n");
  1122.             free_expression(p->left);
  1123.             p->flags=MINUS;
  1124.             p->left=p->right;
  1125.             p->right=0;
  1126.             return(type_expression(p));
  1127.         }
  1128.         /*  0/a=0   */
  1129.         if(null1&&(f==DIV||f==MOD||f==LSHIFT||f==RSHIFT)){
  1130.             if(DEBUG&1) printf("0/%%<<>>a->0\n");
  1131.             p->flags=CEXPR;
  1132.             /*  fier nur int,long,float,double moeglich, hoffe ich  */
  1133.             vlong=l2zl(0L);vulong=zl2zul(vlong);
  1134.             vint=zl2zi(vlong);vuint=zul2zui(vulong);
  1135.             vdouble=zl2zd(vlong);vfloat=zd2zf(vdouble);
  1136.             insert_const(p);
  1137.             if(!p->left->sidefx){free_expression(p->left);p->left=0;}else make_cexpr(p->left);
  1138.             if(!p->right->sidefx){free_expression(p->right);p->right=0;} else make_cexpr(p->right);
  1139.             return(type_expression(p));
  1140.         }
  1141.     }
  1142.     return(1);
  1143. }
  1144. void make_cexpr(np p)
  1145. /*  Macht aus einem Knoten, der durch constant-folding ueberfluessig    */
  1146. /*  wurde, eine PCEXPR, sofern er keine Nebenwirkungen von sich aus     */
  1147. /*  erzeugt. Hier noch ueberpruefen, ob CEXPR besser waere.             */
  1148. /*  Fuehrt rekursiven Abstieg durch. Ist das so korrekt?                */
  1149. {
  1150.     int f=p->flags;
  1151.     if(f!=ASSIGN&&f!=ASSIGNADD&&f!=CALL&&f!=POSTINC&&f!=POSTDEC&&f!=PREINC&&f!=PREDEC){
  1152.         p->flags=PCEXPR;
  1153.         if(p->left) make_cexpr(p->left);
  1154.         if(p->right) make_cexpr(p->right);
  1155.     }
  1156. }
  1157. int test_assignment(struct Typ *zt,np q)
  1158. /*  testet, ob q an Typ z zugewiesen werden darf    */
  1159. {
  1160.     struct Typ *qt=q->ntyp;
  1161.     if(arith(zt->flags&NQ)&&arith(qt->flags&NQ)){
  1162.         if((zt->flags&NQ)<=LONG&&(qt->flags&NQ)<=LONG&&
  1163.            !zlleq(sizetab[qt->flags&NQ],sizetab[zt->flags&NQ])&&q->flags!=CEXPR)
  1164.             error(166);
  1165.         return(1);
  1166.     }
  1167.     if(((zt->flags&NQ)==STRUCT&&(qt->flags&NQ)==STRUCT)||
  1168.        ((zt->flags&NQ)==UNION &&(qt->flags&NQ)==UNION )){
  1169.         if(!compare_pointers(zt,qt,255)){
  1170.             error(38);return(0);}
  1171.         else return(1);
  1172.     }
  1173.     if((zt->flags&NQ)==POINTER&&(qt->flags&NQ)==POINTER){
  1174.         if((zt->next->flags&NQ)==VOID&&(qt->next->flags&NQ)!=FUNKT) return(1);
  1175.         if((qt->next->flags&NQ)==VOID&&(qt->next->flags&NQ)!=FUNKT) return(1);
  1176.         if(!compare_pointers(zt->next,qt->next,(c_flags[7]&USEDFLAG)?NU:NQ)){
  1177.             error(85);
  1178.         }else{
  1179.             if((qt->next->flags&CONST)&&!(zt->next->flags&CONST))
  1180.                 error(91);
  1181.             if((qt->next->flags&VOLATILE)&&!(zt->next->flags&VOLATILE))
  1182.                 error(100);
  1183.             if(qt->next->next&&zt->next->next&&!compare_pointers(zt->next->next,qt->next->next,255))
  1184.                 error(110);
  1185.         }
  1186.         return(1);
  1187.     }
  1188.     if((zt->flags&NQ)==POINTER&&q->flags==CEXPR){
  1189.         eval_constn(q);
  1190.         if(!(zdeqto(d2zd(0.0),vdouble)&&zleqto(l2zl(0L),vlong)&&zuleqto(ul2zul(0UL),vulong)))
  1191.             error(113);
  1192.         return(1);
  1193.     }
  1194.     error(39);return(0);
  1195. }
  1196.  
  1197.